% author : Lei Yinghaonan
% Creation Date : 2021.11.26
% Last Date : 2021.11.28
% brief : Read HDF5 file.

function grid = ReadGrid(filepath,filename)
file = strcat(filepath,filename);

% --- Read Information ---
% the number of blocks(or zones) of filename grid.
grid.nBlock = h5read(file,'/Information/nBlocks');
% block_type, a list of grid type for each block.
% 0--unstruct grid, 1--struct grid.
grid.type = h5read(file,'/Information/block_type');
% block array of block ID,start from 0 of current grid file.
grid.block_idx = h5read(file,'/Information/block_idx');

% --- Read grid ---
% creat a cell array for each block.
grid.mesh = cell(grid.nBlock,1);
% loop for block
for iBlock = 1:grid.nBlock
    
    % Note that the id of zone or block is start from 0.
    % blockStr is the name of each block,such as 'Grid-0',
    % where '0' is block ID.
    blockStr = strcat('/Grid-',num2str(grid.block_idx(iBlock)));
    
    % --- read number of nodes ---
    % For struct grid, iDimensions is ni,nj,nk for nodes.
    % For unstruct grid, iDimensions is num of nodes,faces and cells.
    % Both of these are 3*1 array.
    iDimensions = h5read(file,strcat(blockStr,'/iDimensions'));
    
    % --- read coordinate of each block ---
    % read coordinate for x direction,which is a 1 dim array.
    nodeCoordinateX = h5read(file,strcat(blockStr,'/GridCoordinates/CoordinateX'));
    % creat nodes coordinate for each dimension.
    nodeCoordinate = zeros(size(nodeCoordinateX,1),3);
    nodeCoordinate(:,1) = nodeCoordinateX;
    nodeCoordinate(:,2) = h5read(file,strcat(blockStr,'/GridCoordinates/CoordinateY'));
    nodeCoordinate(:,3) = h5read(file,strcat(blockStr,'/GridCoordinates/CoordinateZ'));
    
    % --- read boundary condition name---
    % the ascii code of name.
    BCNameASCII =  h5read(file,strcat(blockStr,'/BCName/BCName'));
    % change ascii to string.
    BCNameStr = InitBCName(BCNameASCII);
    
    % ---read interface information---
    % nIFace : the link id of face to adjacent block.
    nIFace = h5read(file,strcat(blockStr,'/InterfaceInfo/nIFace'));
    
    grid.mesh{iBlock}.iDimensions = iDimensions;
    grid.mesh{iBlock}.coordinate = nodeCoordinate;
    grid.mesh{iBlock}.BCNameStr = BCNameStr;
    grid.mesh{iBlock}.nIFace = nIFace;
    
    if(grid.type(iBlock) ==0)
        % --- read unstruct grid---
        
        % the dimension of grid,such as 2d or 3d.
        nDim = InitUnstructDim(grid.mesh{iBlock});
        
        % The interface point information.
        nIPoint = h5read(file,strcat(blockStr,'/InterpointInfo/nIPoint'));
        
        % ---Topology of face.----
        BcType = h5read(file,strcat(blockStr,'/FaceTopology/BcType'));
        % topo of face 2 node.
        face2Node = h5read(file,strcat(blockStr,'/FaceTopology/face2Node'));
        nodeNumberOfEachFace = h5read(file,strcat(blockStr,'/FaceTopology/nodeNumberOfEachFace'));
        % topo of face 2 cell.
        leftCellOfFace = h5read(file,strcat(blockStr,'/FaceTopology/leftCellOfFace'));
        rightCellOfFace = h5read(file,strcat(blockStr,'/FaceTopology/rightCellOfFace'));
        nBoundFace = h5read(file,strcat(blockStr,'/FaceTopology/nBoundFace'));
        
        % ---Topology of cell---
        cell2Node = h5read(file,strcat(blockStr,'/CellTopology/cell2Node'));
        nodeNumberOfEachCell = h5read(file,strcat(blockStr,'/CellTopology/nodeNumberOfEachCell'));
        
        grid.mesh{iBlock}.nDim = nDim;
        grid.mesh{iBlock}.nIPoiont = nIPoint;
        
        grid.mesh{iBlock}.face.BCType = BcType;
        grid.mesh{iBlock}.face.face2Node = face2Node;
        grid.mesh{iBlock}.face.leftCellOfFace =leftCellOfFace;
        grid.mesh{iBlock}.face.rightCellOfFace =rightCellOfFace;
        grid.mesh{iBlock}.face.nBoundFace = nBoundFace;
        grid.mesh{iBlock}.face.nodeNumberOfEachFace = nodeNumberOfEachFace;
        
        grid.mesh{iBlock}.cell.cell2Node = cell2Node;
        grid.mesh{iBlock}.cell.nodeNumberOfEachCell = nodeNumberOfEachCell;
        
    elseif(grid.type(iBlock) ==1)
        % --- read struct grid---
        
        % the dimension of grid,such as 2d or 3d.
        nDim = InitStructDim(grid.mesh{iBlock});
        
        % change coordinate from 1d to 3d for struct grid.
        nodeCoordinateArray = InitFortranArray3D(iDimensions,nodeCoordinate);
        
        % number of boundary condition.
        nBCRegion = h5read(file,strcat(blockStr,'/BCRegion/nBCRegion'));
        % information of boundary condition.
        % The rows corresponds to each boundary.
        % Columns 1 to 6 : ist,ied,jst,jed,kst,ked.
        % Columns 7 : bcType.
        % Columns 8 : sLr, -1 left, 1 right, 0 partition.
        % Columns 9 : sNd, direction , 0--i, 1--j, 2--k;
        BCInfor = h5read(file,strcat(blockStr,'/BCRegion/BCInfor'));
        
        grid.mesh{iBlock}.nDim = nDim;
        
        grid.mesh{iBlock}.nodeCoordinateArray = nodeCoordinateArray;
        grid.mesh{iBlock}.nBCRegion = nBCRegion;
        grid.mesh{iBlock}.BCInfor = BCInfor;
        
    else
        error('error on block type');
    end
    
end